import {Injectable} from "@angular/core";
import {Events, ToastController,AlertController} from "ionic-angular";
import {HttpErrorResponse} from "@angular/common/http";
import {ToastService} from "./toast.service";
import {UnlockService} from "../native/authentication/authentication.service";
import {AdpMenuController} from "../../components/common/adp-menu/adp-menu.controller";
import {tryCatch} from "rxjs/util/tryCatch";
import {_catch} from "rxjs/operator/catch";

@Injectable()
export class HttpErrorHandlerService {
    constructor(private events: Events,
                private toastCtrl: ToastController,
                private alert: AlertController,
                private toastService: ToastService,
                private unlockService: UnlockService,
                private menuCtrl: AdpMenuController) {

        this.events.subscribe("http:error", this.errorCodeHandler);
    }

    private errorCodeHandler = (error: HttpErrorResponse) => {
        // console.log("http:error subscribor")
        const errorCode = error.status;
        let errorObj =  error.error ;
        try{
            if(typeof(error.error) == 'string'){
                errorObj = JSON.parse(error.error);
            }
        }catch(err){
            this.toastService.showToast('啊哦，服务器开小差了，请稍后重试');
        }
        if(error.name =="TimeoutError"){
            this.toastService.showToast('请求服务超时，请稍后重试');
        }
        //当请求的类型为blob时，错误信息会报错在Blob中，所以需要单独的方式来读取Blob错误信息
        else if (error instanceof HttpErrorResponse && error.error instanceof Blob && error.error.type === "application/json") {
            let reader = new FileReader();
            reader.onload = (e: Event) => {
                let errorObj = JSON.parse((<any>e.target).result);
                if (errorCode === 500) {
                    this.error500(errorObj);
                }
            }
            reader.readAsText(error.error, 'utf-8');

        }
        else {
            if (errorCode === 401 && error.error=="invalid_token") {
                this.promptReLogin('登录失效，请重新登录',false);
                if (localStorage.getItem('tokenExpireUpdated') == '0') {
                    localStorage.setItem('tokenExpireUpdated', '1');
                }
            }
            if (errorCode === 400) {
                if (errorObj !== null && errorObj.error === "invalid_grant") {
                    //todo 后端提示
                    let message: string;
                    localStorage.getItem('lang') === ('zh') ? message = '您输入的用户名或密码有误' : message = errorObj.error_description;
                    this.toastService.showToast(message);
                }

            }
            if (errorCode < 200 || (errorCode >= 300 && errorCode !== 401 && errorCode !== 500)) {
                if(errorCode === 0){
                    this.events.publish('checkNet');
                }else{
                    this.toastService.showToast('啊哦，服务器开小差了，请稍后重试');
                }
            }
            if (errorCode === 500) {
                this.error500(errorObj);
            }
        }
        throw error;
    }

    private promptInvalidLogin() {
        setTimeout(() => {
            let toast = this.toastCtrl.create({
                message: '登录失效，请重新登录',
                showCloseButton: true,
                position: 'middle',
                closeButtonText: '确定'
            });
            this.menuCtrl.hideMenu();
            toast.onDidDismiss(() => {
                //localStorage.clear();
                this.unlockService.lockout(true);
            });
            toast.present();
        }, 500);
    }

    //重新登录
    private promptReLogin(message,needTip=true) {
        let reLoginFlag = localStorage.getItem('ReLoginFlag');
        if (!reLoginFlag || reLoginFlag !== "true") {
            //先退出并跳转到登录页，然后提示
            this.menuCtrl.hideMenu();
            if(needTip){//需要提示，然后点击确定跳转到登录页
                setTimeout(() => {
                    let toast = this.alert.create({
                        message:message,
                        cssClass:"custom-alert",
                        buttons:[{
                            text:'确定',
                            handler:()=>{
                                this.unlockService.lockout(true);
                            }
                        }]
                    });
                    toast.present();
                }, 500);
                this.unlockService.lockout(true);
            }else{
                this.unlockService.lockout(true);//不提示，直接跳转到登录页
            }
            localStorage.setItem('ReLoginFlag',"true");
        }
        localStorage.removeItem('SetAlias');
    }

    //错误码为500时处理逻辑
    private error500(errorObj) {
        if (errorObj.status == 995) {
            this.toastService.showToast('啊哦，服务器开小差了，请稍后重试');
        }
        // else if(errorObj.status == 999){
        //     this.toastService.showToast('网络错误');
        // }
        else if(errorObj.status == undefined || errorObj.status == null ){
            this.toastService.showToast('啊哦，服务器开小差了，请稍后重试');
            //此处仅提示无状态码的异常，包含状态码的异常自行提示，如：500
        } else if (errorObj.status == 998) {
            this.promptReLogin('当前用户名已在其它设备登录');
        } else if (errorObj.status == 997) {
            this.promptReLogin('Token过期',false);
        } else if (errorObj.status == 994) {
            this.promptReLogin('当前用户名已被注销');
        } else if (errorObj.status == 993) {
            this.promptReLogin('AWS密码已修改，请重新登录');
        }
    }
}
